//------------------------------------------------------------------------------
#include <QSqlRecord>
#include <QSqlField>
#include "CDAOManager.h"
#include "CMySQL.h"
#include <QtDebug>
//------------------------------------------------------------------------------
CDAOManager *CDAOManager::instance=0;
//------------------------------------------------------------------------------
CDAOManager * CDAOManager::getInstance(void) {		
	if(instance == 0) {	
		instance=new CDAOManager();
	}
	
	return instance;
}
//------------------------------------------------------------------------------
QString CDAOManager::makeCondition(QStringList keys, CGlobal::ESens sens) {
	int i;
	QString condition=" WHERE ";
	QString s="";
	
	if(sens == CGlobal::sePremier || sens == CGlobal::seDernier) {
		return "";
	}
	
	for(i=0;i<keys.size();i++) {
		condition+=s+"`"+keys.at(i)+"`";
		
		switch(sens) {
			case CGlobal::seNone:
				condition+=" = ";
				break;
			case CGlobal::sePrecedent:
				condition+=" < ";
				break;
			case CGlobal::seSuivant:
				condition+=" > ";
				break;
			default:
				break;
		}
		condition+=s+" :"+keys.at(i);
		
		s=" AND ";
	}
	
	return condition;
}
//------------------------------------------------------------------------------
QString CDAOManager::makeTri(QStringList keys, CGlobal::ESens sens, bool loadAll) {
	int i;
	QString tri=" ORDER BY ";
	QString s="";
	
	for(i=0;i<keys.size();i++) {
		tri+=s+"`"+keys.at(i)+"`";
		
		if(sens == CGlobal::sePrecedent || sens == CGlobal::seDernier) {
			tri+=" DESC";
		}
		s=", ";
	}
	
	if(!loadAll) {
		tri+=" LIMIT 1";
	}
	
	return tri;
}
//------------------------------------------------------------------------------
bool CDAOManager::load(CDAO *daoObject, QMap<QString, QVariant> keyValues, CGlobal::ESens sens) {
	QString requete;
	QString s;
	QSqlQuery *query=CMySQL::getInstance()->getQuery();
	const QStringList keys=daoObject->getKeys();
	QSqlRecord rec;
	int i;
	bool ret=false;
	
	requete="SELECT * FROM `"+daoObject->getTableName()+"`"+makeCondition(keys, sens)+makeTri(keys, sens, keys.size() == keyValues.size())+" LIMIT 1";
	
	query->prepare(requete);
	if(sens == CGlobal::seNone || sens == CGlobal::sePrecedent || sens ==CGlobal::seSuivant) {
		QMapIterator<QString, QVariant> iter(keyValues);
		while(iter.hasNext()) {
			iter.next();
			query->bindValue(":"+iter.key(), iter.value());
		}
	}
	
	if(CMySQL::getInstance()->execQuery(query)) {
		if(query->next()) {
			rec=query->record();
		
			for(i=0;i<rec.count();i++) {
				daoObject->set(rec.field(i).name(), rec.value(i));
			}
			
			ret=true;
		}
	}
	
	return ret;
}
//------------------------------------------------------------------------------
bool CDAOManager::update(CDAO *daoObject) {
	QString requete="UPDATE `"+daoObject->getTableName()+"` SET ";
	QString sU="";
	QString sC="";
	int i;
	QStringList fields=daoObject->getFields();
	QStringList keys=daoObject->getKeys();
	QSqlQuery *query=CMySQL::getInstance()->getQuery();
	QString condition=" WHERE ";
	
	for(i=0;i<fields.size();i++) {
		if(!keys.contains(fields.at(i))) {
			requete+=sU+"`"+fields.at(i)+"` = :"+fields.at(i);
			
			sU=", ";
		}else {
			condition+=sC+"`"+fields.at(i)+"` = :"+fields.at(i); 
			
			sC=" AND ";
		}
	}
	
	requete+=condition;
	
	query->prepare(requete);
	
	for(i=0;i<fields.size();i++) {
		query->bindValue(":"+fields.at(i), daoObject->get(fields.at(i)));
	}
	
	
	return CMySQL::getInstance()->execQuery(query);
}
//------------------------------------------------------------------------------
bool CDAOManager::insert(CDAO *daoObject) {
	QString requete="INSERT INTO `"+daoObject->getTableName()+"` (";
	QString s="";
	int i;
	QStringList fields=daoObject->getFields();
	QStringList keys=daoObject->getKeys();
	QSqlQuery *query=CMySQL::getInstance()->getQuery();
	QString values="VALUES (";
	
	for(i=0;i<fields.size();i++) {
		requete+=s+"`"+fields.at(i)+"`";
		values+=s+":"+fields.at(i);
		s=", ";
	}
	
	requete+=") "+values+")";
	
	query->prepare(requete);
	
	for(i=0;i<fields.size();i++) {
		query->bindValue(":"+fields.at(i), daoObject->get(fields.at(i)));
	}
	
	return CMySQL::getInstance()->execQuery(query);
}
//------------------------------------------------------------------------------
bool CDAOManager::drop(CDAO *daoObject, QMap<QString, QVariant> keyValues) {
	QString requete="DELETE FROM `"+daoObject->getTableName()+"` WHERE ";
	QString s="";
	QStringList keys=daoObject->getKeys();
	QSqlQuery *query=CMySQL::getInstance()->getQuery();
	int i;
	
	for(i=0;i<keys.size();i++) {
		requete+=s+"`"+keys.at(i)+"`=:"+keys.at(i);
		s=" AND ";
	}
	
	query->prepare(requete);
	
	QMapIterator<QString, QVariant> iter(keyValues);
	while(iter.hasNext()) {
		iter.next();
		query->bindValue(":"+iter.key(), iter.value());
	}
	
	return CMySQL::getInstance()->execQuery(query);
}
//------------------------------------------------------------------------------
int CDAOManager::getNbEnregistrement(CDAO *daoObject) {
	return CMySQL::getInstance()->getNbEnregistrement(daoObject->getTableName());
}
//------------------------------------------------------------------------------
QDate CDAOManager::getCurrentDate(void)
{
	QDate d;
	QString requete;
	QSqlQuery *query;
	
	requete="SELECT CURDATE()";
	if(!CMySQL::getInstance()->execQuery(requete, &query))
	{
		delete query;
		return QDate();
	}
	
	if(query->next())
	{
		d=query->record().value(0).toDate();
	}
	
	delete query;
	
	return d;
}
//------------------------------------------------------------------------------
QTime CDAOManager::getCurrentTime(void)
{
	QTime t;
	QString requete;
	QSqlQuery *query;
	
	requete="SELECT CURTIME()";
	if(!CMySQL::getInstance()->execQuery(requete, &query))
	{
		delete query;
		return QTime();
	}
	
	if(query->next())
	{
		t=query->record().value(0).toTime();
	}
	
	delete query;
	
	return t;
}
//------------------------------------------------------------------------------
int CDAOManager::loadDoc2Print(QString frmName, QList<CDAODocToPrintEx *> *list) {
	QString requete="SELECT dtc.id, dtc.frmName, dtc.reportTitle, dtc.reportName, dtc.render, ";
	requete+="dtc.docNameField, dtcf.fieldName, dtcf.tableName, dtcf.champName ";
	requete+="FROM docToPrint AS dtc ";
	requete+="INNER JOIN docToPrintField AS dtcf ON dtcf.idDocToPrint=dtc.id ";
	requete+="WHERE dtc.frmName='"+frmName+"'";
	QSqlQuery *query;
	int oldId=0;
	CDAODocToPrintEx *docToPrint;
	int nb=0;
	
	if(!CMySQL::getInstance()->execQuery(requete, &query)) {
		delete query;
		return 0;
	}
	
	while(query->next()) {
		QSqlRecord record=query->record();
		int newId=record.value("id").toInt();
		CDAODocToPrintField *field=new CDAODocToPrintField();
		
		if(newId != oldId) {
			docToPrint=new CDAODocToPrintEx();
		
			docToPrint->setFieldId(record.value("id"));
			docToPrint->setFieldFrmName(record.value("frmName"));
			docToPrint->setFieldReportTitle(record.value("reportTitle"));
			docToPrint->setFieldReportName(record.value("reportName"));
			docToPrint->setFieldRender(record.value("render"));
			docToPrint->setFieldDocNameField(record.value("docNameField"));
		
			list->append(docToPrint);
			
			nb++;
		}
		
		field->setFieldFieldName(record.value("fieldName"));
		field->setFieldTableName(record.value("tableName"));
		field->setFieldChampName(record.value("champName"));
		
		docToPrint->append(field);
		
		oldId=newId;
	}
	delete query;
	
	return nb;
	
}
//------------------------------------------------------------------------------
